package com.zy.swagger.util;

import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Calendar;
import java.util.Date;
import java.util.List;


/**
 * @author Administrator
 */
@Slf4j
public class DateUtil {

    /** yyyy/MM/dd格式 */
    public static final String SHORT_PATTERN_1 = "yyyy/MM/dd";

    /** 时间格式(yyyy-MM-dd) */
    public final static String SHORT_PATTERN_2 = "yyyy-MM-dd";

    /** yyyy.MM.dd格式 */
    public static final String SHORT_PATTERN_3 = "yyyy.MM.dd";

    /** yy_MM_dd格式 */
    public static final String SHORT_PATTERN_4 = "yy_MM_dd";

    public static final String SHORT_PATTERN_5 = "HH:mm";

    /** yyyy/MM/dd HH:mm:ss格式 */
    public static final String NORMAL_PATTERN_1 = "yyyy/MM/dd HH:mm:ss";

    /** 时间格式(yyyy-MM-dd HH:mm:ss) */
    public final static String NORMAL_PATTERN_2 = "yyyy-MM-dd HH:mm:ss";

    /** yyyy.MM.dd HH:mm:ss 格式 */
    public static final String NORMAL_PATTERN_3 = "yyyy.MM.dd HH:mm:ss";
	
	public static String format(Date date) {
        return format(date, SHORT_PATTERN_2);
    }

    public static String format(Date date, String pattern) {
        if(date != null){
            SimpleDateFormat df = new SimpleDateFormat(pattern);
            return df.format(date);
        }
        return null;
    }

    public static String getBeginDateStr(int year, int month) {
        YearMonth yearMonth = YearMonth.of(year, month);
        LocalDate localDate = yearMonth.atDay(1);
        LocalDateTime startOfDay = localDate.atStartOfDay();
        ZonedDateTime zonedDateTime = startOfDay.atZone(ZoneId.of("Asia/Shanghai"));

        return DateUtil.formatDate(Date.from(zonedDateTime.toInstant()), DateUtil.SHORT_PATTERN_2);
    }

    public static String getEndDateStr(int year, int month) {
        YearMonth yearMonth = YearMonth.of(year, month);
        LocalDate endOfMonth = yearMonth.atEndOfMonth();
        LocalDateTime localDateTime = endOfMonth.atTime(23, 59, 59, 999);
        ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of("Asia/Shanghai"));
        return DateUtil.formatDate(Date.from(zonedDateTime.toInstant()), DateUtil.SHORT_PATTERN_2);
    }

    /**
     * 获取距离当前日期前/后 n 天的日期
     *
     * @param n 传正数表示n天后，传负数表示n天前
     * @return
     */
    public static Date getDate(int n) {
        //计算n天前/后的日期
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        cal.add(Calendar.DATE, n);
        return cal.getTime();
    }

    /**
     * 获取距离给定日期前/后 n 天的日期
     *
     * @param n 传正数表示n天后，传负数表示n天前
     * @return
     */
    public static Date getDate(Date date, int n) {
        //计算昨天的日期
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DATE, n);
        return cal.getTime();
    }

    /**
     * 格式化日期
     *
     * @param date
     * @param pattern
     * @return
     */
    public static String formatDate(Date date, String pattern) {
        return new SimpleDateFormat(pattern).format(date);
    }

    /**
     * 将日期字符串按给定格式解析为日期
     *
     * @param dateStr
     * @param pattern
     * @return
     * @throws Exception
     */
    public static Date parseDate(String dateStr, String pattern) throws Exception {
        return new SimpleDateFormat(pattern).parse(dateStr);
    }

    /**
     * 计算两个日期间一共有多少天(包括起始时间，即算头也算尾)
     *
     * @param date1
     * @param date2
     * @return
     */
    public static int calcBetweenDays(Date date1, Date date2) {
        long betweenDays = (date1.getTime() - date2.getTime()) / (1000 * 3600 * 24);
        return Math.abs((int) betweenDays);
    }

    /**
     * 根据前端参数获取对应的日期集合
     *
     * @param dateType  1.今天 2.昨天 3.最近7天 4.最近30天 5.自定义范围
     * @param dateRange 类型为5时，必传
     * @param max       最大间隔天数
     * @return
     * @throws Exception
     */
    public static List<String> getDateList(Integer dateType, String dateRange, Integer max) {
        List<String> dateList = Lists.newArrayList();
        Date date;
        switch (dateType) {
            // 默认返回 今天
            default:
                date = DateUtil.getDate(0);
                dateList.add(DateUtil.formatDate(date, DateUtil.SHORT_PATTERN_2));
                break;
            // 昨天
            case 2:
                date = DateUtil.getDate(-1);
                dateList.add(DateUtil.formatDate(date, DateUtil.SHORT_PATTERN_2));
                break;

            // 最近7天
            case 3:
                for (int i = 6; i >= 0; i--) {
                    date = DateUtil.getDate(-i);
                    dateList.add(DateUtil.formatDate(date, DateUtil.SHORT_PATTERN_2));
                }
                break;

            // 最近30天
            case 4:
                for (int i = 29; i >= 0; i--) {
                    date = DateUtil.getDate(-i);
                    dateList.add(DateUtil.formatDate(date, DateUtil.SHORT_PATTERN_2));
                }
                break;

            // 选择时间段
            case 5:
                String[] dateRangeArr = dateRange.split("~");
                Date startDate = null;
                Date endDate = null;
                try {
                    if (dateRange.contains("/")) {
                        startDate = DateUtil.parseDate(dateRangeArr[0], DateUtil.SHORT_PATTERN_1);
                        endDate = DateUtil.parseDate(dateRangeArr[1], DateUtil.SHORT_PATTERN_1);
                    } else if (dateRange.contains("-")) {
                        startDate = DateUtil.parseDate(dateRangeArr[0], DateUtil.SHORT_PATTERN_2);
                        endDate = DateUtil.parseDate(dateRangeArr[1], DateUtil.SHORT_PATTERN_2);
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                    log.error("解析日期异常：", e);
                }
                if (startDate == null || endDate == null) {
                    return dateList;
                }
                // 检验手动输入的两个日期差值是否超过90天
                int betweenDays = DateUtil.calcBetweenDays(startDate, endDate);
                if (betweenDays > max || betweenDays < 0) {
                    throw new RuntimeException("日期范围超限");
                }
                for (int i = betweenDays; i >= 0; i--) {
                    date = DateUtil.getDate(endDate, -i);
                    dateList.add(DateUtil.formatDate(date, DateUtil.SHORT_PATTERN_2));
                }
                break;
        }
        return dateList;
    }


}
